package com.glsc.ngateway.opmanage.service.deposit;


import com.glsc.ngateway.common.api.common.utils.PageUtil;
import com.glsc.ngateway.common.base.domain.mysql.opmanagemain.deposit.DepositoryBank;
import com.glsc.ngateway.common.base.domain.mysql.opmanagemain.deposit.DepositoryDayEndTrial;
import com.glsc.ngateway.common.base.domain.mysql.opmanagemain.deposit.DepositoryDayEndTrialCcb;
import com.glsc.ngateway.common.base.domain.mysql.opmanagemain.deposit.DepositoryDayStartData;
import com.glsc.ngateway.common.base.domain.oracle.xinyizj.FsBankBal;
import com.glsc.ngateway.common.base.repo.mysql.opmanagemain.deposit.DepositoryDayEndTrialRepository;
import com.glsc.ngateway.opmanage.utils.DateUtils;
import com.glsc.ngateway.opmanage.utils.SpecificationUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang.StringUtils;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.transaction.Transactional;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;


/**
 * 保证金每日试算(新)日终
 */

@Service
public class DepositoryDayEndTrialService {

    @Resource
    private DepositoryDayEndTrialRepository depositoryDayEndTrialRepository;

    @Resource
    private DepositoryBankService depositoryBankService;

    @Resource
    private DepositoryDayStartDataService depositoryDayStartDataService;

    @Resource
    private FsBankBalService fsBankBalService;

    @Resource
    private FsBankVouService fsBankVouService;

    @Resource
    private DepositoryDayEndTrialCcbService depositoryDayEndTrialCcbService;


    /**
     * 创建每日数据（日终）
     */
    @Transactional
    public void createDate() {
        List<DepositoryBank> banks = depositoryBankService.listAll();
        if (CollectionUtils.isEmpty(banks)) {
            return;
        }

        List<DepositoryDayEndTrial> resList = Lists.newArrayList();

        //删除今日数据重新生成
        List<DepositoryDayEndTrial> trials = listByDate(DateUtils.getNowDateString());
        if (CollectionUtils.isNotEmpty(trials)) {
            deleteByIds(trials.stream().map(DepositoryDayEndTrial::getId).collect(Collectors.toList()));
        }
        BigDecimal nanJingInsert = BigDecimal.ZERO;
        //生成今日数据
        for (DepositoryBank bank : banks) {
            //备付金不进行相关计算
            if (bank.getBankName().contains("备付金")) {
                continue;
            }

            DepositoryDayEndTrial trial = DepositoryDayEndTrial.builder().deleted("N").bankName(bank.getBankName())
                    .interestRate(bank.getInterestRate()).build();

            trial.setEffectDate(DateUtils.getNowDateString());

            resList.add(trial);

            if (Objects.nonNull(bank.getDepositFloorType())) {
                if (bank.getDepositFloorType().equals("1")) {
                    //T日日终预设存放比   读取存管银行配置中的数据
                    trial.setStowageRate(bank.getDepositFloor());
                } else {
                    //T日日终最低存放金额  读取存管银行配置中的数据
                    trial.setStowageLowAmount(bank.getDepositFloor());
                }
            }

            //新意资金结算系统取T日16:00账户余额
            trial.setAccountBalance(BigDecimal.ZERO);
            //新意资金结算系统取数当日银证转账金额
            trial.setBankSecTranBalance(BigDecimal.ZERO);
            //新意资金结算系统取数前一日柜台余额
            trial.setPreCounterBalance(BigDecimal.ZERO);


            //  补充新意结算系统柜台余额
            DepositoryDayStartData data = depositoryDayStartDataService.findByBankAccToday(bank.getAccount());
            if (Objects.nonNull(data)) {
                //新意资金结算系统取数前一日柜台余额
                if (Objects.nonNull(data.getMarginGtAmt())) {
                    trial.setPreCounterBalance(data.getMarginGtAmt());
                }

                if (Objects.nonNull(data.getMarginTotalAmt())) {
                    trial.setAccountBalance(data.getMarginTotalAmt());
                }

                if (Objects.nonNull(data.getBankSecTranBalance())) {
                    trial.setBankSecTranBalance(data.getBankSecTranBalance());
                }
            }

            //  补充新意结算系统账户余额
           // FsBankBal fsBankBal = fsBankBalService.findByBankAcc(bank.getAccount());
           /* if (Objects.nonNull(fsBankBal) && Objects.nonNull(fsBankBal.getAccBal())) {
                trial.setAccountBalance(fsBankBal.getAccBal());
            }*/

            //  补充新意结算系统银证转账金额
            //BigDecimal yzAmount = fsBankVouService.calYzAmount(bank.getAccount());
            /*if (Objects.nonNull(yzAmount)) {
                trial.setBankSecTranBalance(yzAmount);
            }*/

            //计算数据
            //初始化空数据为0
            if (Objects.isNull(trial.getAccountBalance())) {
                trial.setAccountBalance(BigDecimal.ZERO);
            }
            if (Objects.isNull(trial.getBankSecTranBalance())) {
                trial.setBankSecTranBalance(BigDecimal.ZERO);
            }
            if (Objects.isNull(trial.getPreCounterBalance())) {
                trial.setPreCounterBalance(BigDecimal.ZERO);
            }
            if (Objects.isNull(trial.getAdjustValue())) {
                trial.setAdjustValue(BigDecimal.ZERO);
            }
            if (Objects.isNull(trial.getAdjustBalance())) {
                trial.setAdjustBalance(BigDecimal.ZERO);
            }


            //T日预估柜台余额 = 银证转账金额 + 上一日保证金柜台余额
            trial.setCurrentCounterBalance(trial.getPreCounterBalance().add(trial.getBankSecTranBalance()));

            //调整后余额
            if (Objects.nonNull(bank.getDepositFloorType())) {
                if (bank.getDepositFloorType().equals("1")) {
                    //最低存放比 value= T日预估柜台余额 * 最低存放比
                    trial.setAdjustBalance(trial.getCurrentCounterBalance().multiply(trial.getStowageRate()).setScale(2, RoundingMode.HALF_UP).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP));
                } else {
                    //最低存放金额 value = 最低存放金额
                    //trial.setAdjustBalance(trial.getAdjustBalance().subtract(trial.getStowageLowAmount()));
                    trial.setAdjustBalance((trial.getStowageLowAmount()));
                }
            }

            /**
             * 南京银行的 T日日终调整值 需要与其他银行的调整值加和做“反冲”
             */
            if (!bank.getBankName().contains("南京存管0019")) {
                //T日日终调整值 =调整后余额 - 账户余额
                trial.setAdjustValue(trial.getAdjustBalance().subtract(trial.getAccountBalance()).setScale(2, RoundingMode.HALF_UP));
            }else {
                nanJingInsert = bank.getInterestRate();
            }

            //T日日终存放比 = 调整后余额/T日预估柜台余额
            if (Objects.nonNull(bank.getDepositFloorType())) {
                if (Objects.nonNull(trial.getCurrentCounterBalance()) && trial.getCurrentCounterBalance().compareTo(BigDecimal.ZERO) != 0) {
                    trial.setActualStowageRate(trial.getAdjustBalance().divide(trial.getCurrentCounterBalance(), 4, RoundingMode.HALF_UP).setScale(4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)));
                    //T日日终预计利息 =调整后余额 * 利息 / 360
                    trial.setInterest(trial.getAdjustBalance().multiply(bank.getInterestRate()).divide(BigDecimal.valueOf(36000), 2, RoundingMode.HALF_UP));
                }
            }
        }

        //todo 计算建行3568的值
        DepositoryDayEndTrialCcb ccb = depositoryDayEndTrialCcbService.findByNameAndDate("建行3568", DateUtils.getNowDateString());
        DepositoryDayEndTrial jianHang3568 = DepositoryDayEndTrial.builder().accountBalance(BigDecimal.ZERO)
                .adjustBalance(BigDecimal.ZERO).bankName("建行3568").adjustValue(BigDecimal.ZERO).effectDate(DateUtils.getNowDateString()).deleted("N").build();
        if (Objects.nonNull(ccb) && Objects.nonNull(ccb.getAccountBalance())) {
            jianHang3568.setAdjustValue(BigDecimal.ZERO.subtract(ccb.getAccountBalance()));
        }
        resList.add(jianHang3568);

        if (CollectionUtils.isNotEmpty(resList)) {

            List<DepositoryDayEndTrial> list = resList.stream().filter(e -> e.getBankName().contains("南京存管0019")).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(list)) {
                DepositoryDayEndTrial nanJing0019 = list.get(0);
                BigDecimal sumAdjust = BigDecimal.ZERO;
                for (DepositoryDayEndTrial trial : resList) {
                    if (Objects.nonNull(trial.getAdjustValue())) {
                        sumAdjust = sumAdjust.add(trial.getAdjustValue());
                    }
                }
                nanJing0019.setAdjustValue(BigDecimal.ZERO.subtract(sumAdjust));
                nanJing0019.setAdjustBalance(nanJing0019.getAdjustValue().add(nanJing0019.getAccountBalance()));
                nanJing0019.setInterest(nanJing0019.getAdjustBalance().multiply(nanJingInsert).divide(BigDecimal.valueOf(36000), 2, RoundingMode.HALF_UP));
            }

            depositoryDayEndTrialRepository.saveAll(resList);
        }


    }


    /**
     * 分页查找
     *
     * @param pageNo
     * @param pageSize
     * @param param
     * @return
     */
    public Page<DepositoryDayEndTrial> page(int pageNo, int pageSize, Map<String, Object> param) {
        Sort.Direction direction = Sort.Direction.DESC;
        String sort = "createTime";

        pageNo = PageUtil.initPageNo(pageNo);
        pageSize = PageUtil.initPageSize(pageSize);

        Pageable pageable = PageRequest.of(pageNo - 1, pageSize, direction, sort);
        Page<DepositoryDayEndTrial> page = depositoryDayEndTrialRepository.findAll(SpecificationUtil.buildSpecification(param, DepositoryDayEndTrial.class), pageable);

        return page;
    }

    /**
     * 根据id查找
     *
     * @param id
     * @return
     */
    public DepositoryDayEndTrial findById(Integer id) {
        if (Objects.isNull(id)) {
            return null;
        }
        Optional<DepositoryDayEndTrial> optional = depositoryDayEndTrialRepository.findById(id);
        if (optional.isPresent()) {
            return optional.get();
        }
        return null;
    }

    /**
     * 保存
     *
     * @param obj
     * @return
     */
    public DepositoryDayEndTrial save(DepositoryDayEndTrial obj) {
        if (Objects.isNull(obj)) {
            return null;
        }
        DepositoryDayEndTrial save = depositoryDayEndTrialRepository.save(obj);
        return save;
    }


    /**
     * 根据生效日期查询所有的日终数据
     *
     * @param effectDate
     * @return
     */
    public List<DepositoryDayEndTrial> listByDate(String effectDate) {
        if (StringUtils.isEmpty(effectDate)) {
            return null;
        }
        List<DepositoryDayEndTrial> trials = depositoryDayEndTrialRepository.findAll(Example.of(DepositoryDayEndTrial.builder().effectDate(effectDate).build()));
        return trials;
    }


    /**
     * 根据id进行删除
     *
     * @param id
     */
    public void deleteById(Integer id) {
        if (Objects.isNull(id)) {
            return;
        }
        depositoryDayEndTrialRepository.deleteById(id);
    }


    /**
     * 根据id删除所有的数据
     *
     * @param ids
     */
    public void deleteByIds(List<Integer> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return;
        }
        depositoryDayEndTrialRepository.deleteAllById(ids);
    }

}
